﻿/**
 * @file
 *
 * @brief Demonstrates validation against a schema loaded from a file.
 *
 */

#include <iostream>
#include <stdexcept>

#include <valijson/adapters/jsoncpp_adapter.hpp>
#include <valijson/utils/jsoncpp_utils.hpp>
#include <valijson/schema.hpp>
#include <valijson/schema_parser.hpp>
#include <valijson/validation_results.hpp>
#include <valijson/validator.hpp>
#include "any.hpp"
#include <stack>
using std::cerr;
using std::endl;

using valijson::Schema;
using valijson::SchemaParser;
using valijson::Validator;
using valijson::ValidationResults;
using valijson::adapters::JsonCppAdapter;


int test(Json::Value& schemaDocument, Json::Value& targetDocument,std::string& desc) {
    std::cout << "1" << std::endl;
    // Parse the json schema into an internal schema format
    Schema schema;
    SchemaParser parser;
    JsonCppAdapter schemaDocumentAdapter(schemaDocument);
    try {
        parser.populateSchema(schemaDocumentAdapter, schema);
    }
    catch (std::exception& e) {
        cerr << "Failed to parse schema: " << e.what() << endl;
        return 1;
    }
    std::cout << "2" << std::endl;
    // Perform validation
    Validator validator(Validator::kStrongTypes);
    ValidationResults results;
    JsonCppAdapter targetDocumentAdapter(targetDocument);
    if (!validator.validate(schema, targetDocumentAdapter, &results)) {
        std::cerr << "Validation failed." << endl;
        ValidationResults::Error error;
        unsigned int errorNum = 1;
        while (results.popError(error)) {

            std::string context;
            std::vector<std::string>::iterator itr = error.context.begin();
            for (; itr != error.context.end(); itr++) {
                context += *itr;
            }

            cerr << "Error #" << errorNum << std::endl
                << "  context: " << context << endl
                << "  desc:    " << error.description << endl;
			desc = desc + "Error #" + std::to_string(errorNum)+'\n' + "  context: " + context + '\n' + "  desc:    " + error.description + '\n';
            ++errorNum;
        }
        return 1;
    }
    return 0;
}

/**
 * @brief  string类型字符串分割函数
 * @param  str(string): 待分割字符串
 * @param  separator(string): 分割符号
 * @return result: 分割结果vetor容器
 */
std::string getLastElement(std::string str, const std::string& separator)
{
    std::vector<std::string> result;
    int cutAt;
    while ((cutAt = str.find_first_of(separator)) != str.npos)
    {
        if (cutAt > 0)
        {
            result.push_back(str.substr(0, cutAt));
        }
        str = str.substr(cutAt + 1);
    }
    if (str.length() > 0)
    {
        result.push_back(str);
    }
    
    int num = -1;
    num = result.size() - 1;
    if (num >= 0)
        return std::move(result[num]);

    return "";
}
//{
//"identifier": "生物识别模块:人脸识别功能参数",
//"name" : "人脸识别功能参数",
//"desc" : "人脸识别功能参数",
//"data" : [
//{
//	"identifier": "人脸识别功能开关",
//		"name" : "人脸识别功能开关",
//		"desc" : "人脸识别功能开关",
//		"dataType" : {
//		"type": "bool",
//		"specs" : {
//			"0": "关",
//			"1" : "开"
//		}
//	}
//}
//]
//}
//string string
//number float
//integer  int32
//object   struct
//array    array
//boolean bool
//number double
//date   X
//enum enum
void getSchemaByTslAsHead(Json::Value& schemaPro, Json::Value& tslPro) {
	std::string test; 

	test = tslPro.get("name", "").asString();
	if(!test.empty())
		schemaPro["title"] = test;

	test = tslPro.get("desc", "").asString();
	if (!test.empty())
		schemaPro["description"] = test;
}
void getSchemaByTslAsInt(Json::Value& schemaPro, Json::Value& tslPro) {
	schemaPro["type"] = "integer";
}
void getSchemaByTslAsString(Json::Value& schemaPro, Json::Value& tslPro) {
	schemaPro["type"] = "string";
}
void getSchemaByTslAsFloat(Json::Value& schemaPro, Json::Value& tslPro) {
	schemaPro["type"] = "number";
}
void getSchemaByTslAsDouble(Json::Value& schemaPro, Json::Value& tslPro) {
	getSchemaByTslAsHead(schemaPro, tslPro);
	schemaPro["type"] = "number";
}
void getSchemaByTslAsBool(Json::Value& schemaPro, Json::Value& tslPro) {
	schemaPro["enum"].insert(0, 0);
	schemaPro["enum"].insert(1, 1);
}
void getSchemaByTslAsBody(Json::Value& schemaPro, Json::Value& tslPro);
void getSchemaByTslAsHead(Json::Value& schemaPro, Json::Value& tslPro);
void getSchemaByTslAsStruct(Json::Value& schemaPro, Json::Value& tslPro) {
	schemaPro["type"] = "object";
	for (auto itrRoot : tslPro) {
		std::string identifier = itrRoot["identifier"].asString();
		getSchemaByTslAsHead(schemaPro["properties"][identifier.c_str()], itrRoot);
		getSchemaByTslAsBody(schemaPro["properties"][identifier.c_str()], itrRoot["dataType"]);
	}
}
void getSchemaByTslAsEnum(Json::Value& schemaPro, Json::Value& tslPro) {
	int siz = tslPro.size();
	for (int i = 0; i <= siz - 1; i++)
	{
		schemaPro["enum"].insert(i, i);
		//schemaPro["examples"].insert(i, tslPro["value"])
	}
}
void getSchemaByTslAsArray(Json::Value& schemaPro, Json::Value& tslPro) {
	schemaPro["type"] = "array";
	getSchemaByTslAsBody(schemaPro["items"], tslPro["items"]);
}

void getSchemaByTslAsBody(Json::Value& schemaPro, Json::Value& tslPro) {
	std::string type = tslPro["type"].asString();
	if (type == "int") {
		getSchemaByTslAsHead(schemaPro, tslPro);
		getSchemaByTslAsInt(schemaPro,tslPro);
	}
	else if (type == "float" ) {
		getSchemaByTslAsHead(schemaPro, tslPro);
		getSchemaByTslAsFloat(schemaPro, tslPro);
	}
	else if (type == "double") {
		getSchemaByTslAsHead(schemaPro, tslPro);
		getSchemaByTslAsDouble(schemaPro, tslPro);
	}
	else if (type == "string") {
		getSchemaByTslAsHead(schemaPro, tslPro);
		getSchemaByTslAsString(schemaPro, tslPro);
	}
	else if (type == "bool") {
		getSchemaByTslAsHead(schemaPro, tslPro);
		getSchemaByTslAsBool(schemaPro, tslPro);
	}
	else if (type == "enum") {
		getSchemaByTslAsHead(schemaPro, tslPro);
		getSchemaByTslAsEnum(schemaPro, tslPro["specs"]["range"]);
	}
	else if (type == "struct") {
		getSchemaByTslAsHead(schemaPro, tslPro);
		getSchemaByTslAsStruct(schemaPro, tslPro["specs"]);
	}
	else if (type == "array") {
		getSchemaByTslAsHead(schemaPro, tslPro);
		getSchemaByTslAsArray(schemaPro, tslPro["specs"]);
	}
}

void getSchemaProByTslPro(Json::Value& schemaPro, Json::Value& tslPro) {
	for (Json::Value itrRoot : tslPro) {
		//处理头
		std::string identifier = itrRoot["identifier"].asString();
		getSchemaByTslAsHead(schemaPro[identifier.c_str()], itrRoot);
		//处理体
		for (auto itrData : itrRoot["data"]) {
			std::string identifier2 = itrData["identifier"].asString();
			getSchemaByTslAsBody(schemaPro[identifier.c_str()]["properties"][identifier2.c_str()], itrData["dataType"]);
		}
	}
}

void getSchemaEveByTslEve(Json::Value& schemaPro, Json::Value& tslPro) {
	for (Json::Value itrRoot : tslPro) {
		//处理头
		std::string identifier = itrRoot["identifier"].asString();
		getSchemaByTslAsHead(schemaPro[identifier.c_str()], itrRoot);
		//处理体
		for (auto itrData : itrRoot["outputData"]) {
			std::string identifier2 = itrData["identifier"].asString();
			getSchemaByTslAsBody(schemaPro[identifier.c_str()]["properties"][identifier2.c_str()], itrData["dataType"]);
		}
	}
}
void getSchemaActByTslAct(Json::Value& schemaPro, Json::Value& tslPro) {
	for (Json::Value itrRoot : tslPro) {
		//处理头
		std::string identifier = itrRoot["identifier"].asString();
		getSchemaByTslAsHead(schemaPro[identifier.c_str()], itrRoot);
		//处理体
		for (auto itrData : itrRoot["inputData"]) {
			std::string identifier2 = itrData["identifier"].asString();
			getSchemaByTslAsBody(schemaPro[identifier.c_str()]["inputData"]["properties"][identifier2.c_str()], itrData["dataType"]);
		}
		for (auto itrData : itrRoot["outputData"]) {
			std::string identifier2 = itrData["identifier"].asString();
			getSchemaByTslAsBody(schemaPro[identifier.c_str()]["outputData"]["properties"][identifier2.c_str()], itrData["dataType"]);
		}
	}
}
void getSchemaByTsl(Json::Value& tslDocumentRoot) {
	Json::Value schemaDocumentRoot; 
	Json::Value propertiesRoot;
	int proNum = tslDocumentRoot["properties"].size();
	for (Json::Value itrRoot : tslDocumentRoot["properties"]){
		std::string identifier = itrRoot["identifier"].asString();
		propertiesRoot[identifier.c_str()]["title"] = itrRoot["name"].asString();
		propertiesRoot[identifier.c_str()]["description"] = itrRoot["desc"].asString();
		for (auto itrData : itrRoot["data"]) {
			std::string identifier2 = itrData["identifier"].asString();
			propertiesRoot[identifier.c_str()][identifier2.c_str()]["title"] = itrRoot["name"].asString();
			propertiesRoot[identifier.c_str()][identifier2.c_str()]["description"] = itrRoot["desc"].asString();
			std::string type = itrData["dataType"]["type"].asString();
			if (type == "int") {
				propertiesRoot[identifier.c_str()][identifier2.c_str()]["type"] = "integer";
			}
			else if (type == "float"|| type == "double") {
				propertiesRoot[identifier.c_str()][identifier2.c_str()]["type"] = "number";
			}
			else if(type == "string") {
				propertiesRoot[identifier.c_str()][identifier2.c_str()]["type"] = "string";
			}
			else if (type == "bool") {
				propertiesRoot[identifier.c_str()][identifier2.c_str()]["enum"].insert(0, 0);
				propertiesRoot[identifier.c_str()][identifier2.c_str()]["enum"].insert(1, 1);
			}
			else if (type == "enum") {
				int siz =  itrData["dataType"]["specs"]["range"].size();
				for (int i = 0;i<=siz-1;i++)
				{
					propertiesRoot[identifier.c_str()][identifier2.c_str()]["enum"].insert(i, i);
				}
			}
			else if (type == "struct") {

					
			}else if (type == "array") {

			}
		}
	}
}
std::string GetStringByJson(Json::Value& root) {
	constexpr bool shouldUseOldWay = false;
	std::string json_file;
	if (shouldUseOldWay) {
		Json::FastWriter writer;
		json_file = writer.write(root);
		std::cout << json_file << std::endl;
	}
	else {
		Json::StreamWriterBuilder builder;
		json_file = Json::writeString(builder, root);
		std::cout << json_file << std::endl;
	}
	return json_file;
}

struct  ValueL{
public:
	enum Type {
		Invalid = 0,
		Int,
		Float,
		Double,
		String,
		Bool,
		Array,
		Struct
	};
	struct Data
	{
		const char* m_key = nullptr;
		nonstd::any m_baseData;
		int type = Invalid;
	}DataNote;
	ValueL(const char* key, const int val) {
			m_data.type = Int;
			m_data.m_key = key;
			m_data.m_baseData = nonstd::any(val);
		}
		ValueL(const char* key, const float val) {
			m_data.type = Float;
			m_data.m_key = key;
			m_data.m_baseData = nonstd::any(val);
		}
		ValueL(const char* key, const double val) {
			m_data.type = Double;
			m_data.m_key = key;
			m_data.m_baseData = nonstd::any(val);
		}
		ValueL(const char* key, const bool val) {
			m_data.type = Bool;
			m_data.m_key = key;
			m_data.m_baseData = nonstd::any(val);
		}
		ValueL(const char* key, const char* val) {
			m_data.type = String;
			m_data.m_key = key;
			m_data.m_baseData = nonstd::any(val);
		}
		ValueL(const char* key, std::string val) {
			m_data.type = String;
			m_data.m_key = key;
			m_data.m_baseData = nonstd::any(val.c_str());
		}
		//存储数组
		ValueL(const char* key, int len, ValueL::Type type) {
			m_data.type = type;
			m_data.m_key = key;
			m_total = len;
		}
		ValueL(const ValueL & value) {
			m_data.type = value.m_data.type;
			m_data.m_key = value.m_data.m_key;
			m_data.m_baseData = value.m_data.m_baseData;
			m_total = value.m_total;
			m_id = value.m_id;
		}
	~ValueL() {

	}
public:
	bool push_back(ValueL val) {
		if (this->m_data.type != Array)
			return false;
		return true;
	}
	int getValueType() const {
		return m_data.type;
	}
	const char* getkey() const {
		return m_data.m_key;
	}
	nonstd::any getValue() const {
		return m_data.m_baseData;
	}
	int getId() {
		return m_id;
	}
	void setId(int id) {
		m_id = id;
	}
	int getTotal() {
		return m_total;
	}
	void setTotal(int& total) {
		m_total = total;
	}
private:
	//列表坐标
	int m_id = 0;
	int m_total = 1;
	Data m_data;

};
//得到一个root json
Json::Value getJson(Json::Value& root) {
	return root;
}
//添加一个参数
void addJson4(Json::Value& root, ValueL* myDate) {
	std::cout << myDate->getkey() << "  :  " << myDate->getId() << std::endl;
	switch (myDate->getValueType())
	{
	case ValueL::Int:
	{
		//Json::Value test;
		root["通行策略表结构体"][myDate->getkey()] = nonstd::any_cast<int>(myDate->getValue());
		//root=test[myDate->getkey()].asInt();
	}
	break;
	case ValueL::Float:
	{
		//Json::Value test;
		root["通行策略表结构体"][myDate->getkey()] = nonstd::any_cast<float>(myDate->getValue());
		//root = test[myDate->getkey()].asFloat();
	}
	break;
	case ValueL::Double:
	{
		//Json::Value test;
		root["通行策略表结构体"][myDate->getkey()] = nonstd::any_cast<double>(myDate->getValue());
		//root = test[myDate->getkey()].asDouble();
	}
	break;
	case ValueL::String:
	{
		//Json::Value test;
		root["通行策略表结构体"][myDate->getkey()] = nonstd::any_cast<const char*>(myDate->getValue());
		//root = test[myDate->getkey()].asString();
	}
	break;
	case ValueL::Bool:
	{
		//Json::Value test;
		root["通行策略表结构体"][myDate->getkey()] = nonstd::any_cast<bool>(myDate->getValue());
		//root = test[myDate->getkey()].asBool();
	}
	break;
	case ValueL::Array:
	{
		//root[myDate->getkey()] =
	}
	break;
	case ValueL::Struct:
	{
		//root[myDate->getkey()].append(tets["struct"]);
	}
	break;
	default:
		break;
	}
	return;
}
//添加一个参数
void addJson3(Json::Value& root, ValueL* myDate) {
	std::cout << myDate->getkey() << "  :  " << myDate->getId() << std::endl;
	switch (myDate->getValueType())
	{
	case ValueL::Int: 
	{
		root.append(nonstd::any_cast<int>(myDate->getValue()));
	}
		break;
	case ValueL::Float:
	{
		root.append(nonstd::any_cast<float>(myDate->getValue()));
	}
		break;
	case ValueL::Double:
	{
		root.append(nonstd::any_cast<double>(myDate->getValue()));
	}
		break;
	case ValueL::String:
	{
		root.append(nonstd::any_cast<const char*>(myDate->getValue()));
	}
		break;
	case ValueL::Bool:
	{
		root.append(nonstd::any_cast<bool>(myDate->getValue()));
	}
		break;
	case ValueL::Array:
	{
		//root[myDate->getkey()] =
	}
	break;
	case ValueL::Struct:
	{
		//root[myDate->getkey()].append(tets["struct"]);
	}
	break;
	default:
		break;
	}
	return;
}
//添加一个参数
void addJson2(Json::Value& root, ValueL* myDate) {
	std::cout << myDate->getkey() << "  :  " << myDate->getId() << std::endl;
	switch (myDate->getValueType())
	{
		case ValueL::Int:
			root[myDate->getkey()] = nonstd::any_cast<int>(myDate->getValue());
			break;
		case ValueL::Float:
			root[myDate->getkey()] = nonstd::any_cast<float>(myDate->getValue());
			break;
		case ValueL::Double:
			root[myDate->getkey()] = nonstd::any_cast<double>(myDate->getValue());
			break;
		case ValueL::String:
			root[myDate->getkey()] = nonstd::any_cast<const char*>(myDate->getValue());
			break;
		case ValueL::Bool:
			root[myDate->getkey()] = nonstd::any_cast<bool>(myDate->getValue());
			break;
		case ValueL::Array:
		{
			//root[myDate->getkey()]=
		}
		break;
		case ValueL::Struct:
		{
			//root[myDate->getkey()].append(tets["struct"]);
		}
		break;
		default:
			break;
}
return;
}

Json::Value getJsonByMap(std::map<std::string, nonstd::any>& myData) {
	Json::Value myJson;
	for (auto itr: myData)
	{
		std::cout <<"type:"<< itr.second.type().name() << std::endl;
	}
}
class VetcorData
{
public:
	VetcorData() {}
	~VetcorData() {}
	void insert(ValueL& value) {
		m_data.push_back(value);
	}
	void insert(const ValueL& value) {
		m_data.push_back(value);
		m_data[m_data.size() - 1].setId(m_data.size() - 1);
	}
	void showList() {
		for (auto itr : m_data) {
			std::cout << itr.getkey() << "  :  " << itr.getTotal() << std::endl;
		}
	}
	VetcorData& operator[] (std::string key)    //返回引用，这样才可以对返回值赋值
	{
		m_key = key;
		return *this;
	}
	VetcorData& operator[] (int scp)    //返回引用，这样才可以对返回值赋值
	{
		return *this;
	}
	VetcorData& operator<<(ValueL& value) {
		insert(value);
		return *this;
	}
	VetcorData& operator<<(int) {
		int num = m_data.size()-1;
		m_stack.push(num);
		return *this;
	}
	VetcorData& operator>>(int) {
		int key = m_stack.top();
		m_stack.pop();
		int num = m_data.size() - key;
		if (m_data[key].getValueType() == ValueL::Array)
			num--;
		m_data[key].setTotal(num);
		return *this;
	}
	VetcorData& operator<<(const ValueL& value) {
		insert(value);
		return *this;
	}
	VetcorData& operator=(ValueL& value) {
		insert(value);
		return *this;
	}
	VetcorData& operator=(const ValueL& value) {
		insert(value);
		return *this;
	}
	bool isNormal() {
		return m_stack.empty();
	}
	std::vector<ValueL>& getVector()  {
		return m_data;
	}
	std::string m_key;
private:
	std::vector<ValueL> m_data;
	std::stack<int> m_stack;
};

//处理 数组类型的数据
//int main() {
//	Json::Value root;
//	VetcorData object;
//	//ValueL object2("通行策略表结构体");
//	//ValueL array("通行策略表");
//	//插入数组
//	//object.insert(array);
//	object.insert(ValueL("任务令牌1", "sasdasdasdsd"));
//	object.insert(ValueL("响应码2", "200"));
//	object.insert(ValueL("通行策略表3", 18, ValueL::Array));
//	object["通行策略表3"].apend(ValueL("通行策略表结构体4", 6, ValueL::Struct));
//	object["通行策略表3"] = ValueL("1时间段类型5", 0);
//	object["通行策略表3"] = ValueL("1开始时间6", "2022-08-14 15:30:00");
//	object["通行策略表3"] = ValueL("1结束时间7", "2022-08-14 16:30:00");
//	object["通行策略表3"] = ValueL("1识别控制类型8", "900+901+902");
//	object["通行策略表3"] = ValueL("1身份控制类型9", "900+901+902");
//	object["通行策略表3"].apend(ValueL("通行策略表结构体4", 6, ValueL::Struct));
//	object["通行策略表结构体4"] = ValueL("2时间段类型5", 0);
//	object["通行策略表结构体4"] = ValueL("2开始时间6", "2022-08-14 15:30:00");
//	object["通行策略表结构体4"] = ValueL("2结束时间7", "2022-08-14 16:30:00");
//	object["通行策略表结构体4"] = ValueL("2识别控制类型8", "900+901+902");
//	object["通行策略表结构体4"] = ValueL("2身份控制类型9", "900+901+902");
//	object["通行策略表3"].apend(ValueL("通行策略表结构体4", 6, ValueL::Struct));
//	object["通行策略表结构体4"] = ValueL("3时间段类型5", 0);
//	object["通行策略表结构体4"] = ValueL("3开始时间6", "2022-08-14 15:30:00");
//	object["通行策略表结构体4"] = ValueL("3结束时间7", "2022-08-14 16:30:00");
//	object["通行策略表结构体4"] = ValueL("3识别控制类型8", "900+901+902");
//	object["通行策略表结构体4"] = ValueL("3身份控制类型9", "900+901+902");
//	object.insert(ValueL("通行策略表4", 18, ValueL::Array));
//	for (int i = 0; i <= 2; i++) {
//		object["通行策略表4"].apend(ValueL("通行策略表结构体4", 6, ValueL::Struct));
//		object["通行策略表结构体4"] = ValueL("时间段类型5", 0);
//		object["通行策略表结构体4"] = ValueL("开始时间6", "2022-08-14 15:30:00");
//		object["通行策略表结构体4"] = ValueL("结束时间7", "2022-08-14 16:30:00");
//		object["通行策略表结构体4"] = ValueL("识别控制类型8", "900+901+902");
//		object["通行策略表结构体4"] = ValueL("身份控制类型9", "900+901+902");
//	}
//	object.insert(ValueL("任务说明11", "产品贼棒"));
//	object.insert(ValueL("任务故障12", "-1"));
//
//	object.insert(ValueL("通行策略表12", 6, ValueL::Array));
//	for (int i = 0; i <= 1; i++) {
//		object["通行策略表12"].apend(ValueL("通行策略表结构体13", 3, ValueL::Struct));
//		object["通行策略表结构体13"] = ValueL("时间段类型14", 0);
//		object["通行策略表结构体13"] = ValueL("开始时间15", "2022-08-14 15:30:00");
//	}
//	object.insert(ValueL("通行策略表结构体16", 3, ValueL::Struct));
//	object["通行策略表结构体16"] = ValueL("时间段类型17", 0);
//	object["通行策略表结构体16"] = ValueL("开始时间18", "2022-08-14 15:30:00");
//
//	object.insert(ValueL("通行策略表19", 2, ValueL::Array));
//	object["通行策略表19"].apend(ValueL("时间段类型22", 0));
//	object["通行策略表19"].apend(ValueL("开始时间23", "2022-08-14 15:30:00"));
//	object.insert(ValueL("开始时间24", "2022-08-14 15:30:00"));
//	object.insert(ValueL("任务说明10", "产品贼棒"));
//	object.insert(ValueL("任务故障11", "-1"));
//	//object.insert(ValueL("通行策略表3", 3, ValueL::Array));
//	//for (int i = 0; i <= 2; i++) {
//	//	object.apend(ValueL("开始时间3", "2022-08-14 15:30:00"));
//	//}
//	//object.showList();
//	bool isStruct = false;
//	bool isArray = false;
//	int arraySpec = 0;
//	int structSpec = 0;
//	int StructLend = 0;
//	int ArrayLen = 0;
//	std::string structKeyName = "";
//	std::string arrayKeyName = "";
//	Json::Value tets;
//	Json::Value tets2;
//	for (auto itr: object.getVector() ) {
//		if (itr.getValueType() == ValueL::Array) {
//			isArray = true;
//			ArrayLen = itr.m_num;
//			arrayKeyName = itr.getkey();
//			continue;
//		}
//		if (itr.getValueType() == ValueL::Struct) {
//			isStruct = true;
//			StructLend = itr.m_num-1;
//			structKeyName = itr.getkey();
//			if (isArray) {
//				arraySpec++;
//				//if (ArrayLen <= 0) {
//				//	ArrayLen = 0;
//				//	isArray = false;
//				//}
//			}
//			continue;
//		}
//
//		if (isArray) {
//			arraySpec++;
//			//ArrayLen--;
//			if (arraySpec == ArrayLen ) {
//				isArray = false;
//			}
//			if (!isStruct) {
//				addJson3(root[arrayKeyName], &itr);
//				continue;
//			}
//		}
//		if (isStruct)
//		{
//			structSpec+=1;
//			addJson2(tets[structKeyName], &itr);
//			if (structSpec == StructLend) {
//				if (isArray) {
//					root[arrayKeyName].append(tets[structKeyName]);
//				}
//				else if (arraySpec == ArrayLen) {
//					root[arrayKeyName].append(tets[structKeyName]);
//					arraySpec = 0;
//				}
//				else
//				{
//					root[structKeyName] = tets[structKeyName];
//				}
//				tets.clear();
//				structSpec = 0;
//				isStruct = false;
//			}
//			continue;
//		}
//
//		addJson2(root, &itr);
//	}
//	
//
//	//addJson(root, ValueL("任务令牌", "sasdasdasdsd"));
//	//addJson(root, ValueL("响应码", "200"));
//	std::ofstream out6("/mnt/e/contrle_version/modle_code/mvMqttServer/conf/root.txt");
//	out6 << GetStringByJson(root);
//	out6.close();
//
//	//for (auto itr : father)
//	//{
//	//	std::cout << "type:" << itr.second.type().__is_pointer_p() << std::endl;
//	//}
//	return 0;
//}
//int main(int argc, char *argv[])
//{
//	//加载物模型
//	//生成json schema
//	Json::Value tslDocumentRoot;
//	Json::Value schemaDocumentRoot;
//
//	Json::Value targetDocumentRoot;
//	if (!valijson::utils::loadDocument("/mnt/e/contrle_version/modle_code/mvMqttServer/conf/mvMqttServer.json", tslDocumentRoot)) {
//		cerr << "Failed to load tslDocumentRoot." << endl;
//		return 1;
//	}
//	getSchemaProByTslPro(schemaDocumentRoot["properties"], tslDocumentRoot["properties"]);
//	std::ofstream out1("mvMqttServerSchemaPro.txt");
//	out1 << GetStringByJson(schemaDocumentRoot["properties"]);
//	out1.close();
//	getSchemaEveByTslEve(schemaDocumentRoot["events"], tslDocumentRoot["events"]);
//	std::ofstream out2("mvMqttServerSchemaEvent.txt");
//	out2 << GetStringByJson(schemaDocumentRoot["events"]);
//	out2.close();
//	getSchemaActByTslAct(schemaDocumentRoot["actions"], tslDocumentRoot["actions"]);
//	std::ofstream out3("mvMqttServerSchemaAction.txt");
//	out3 << GetStringByJson(schemaDocumentRoot["actions"]);
//	out3.close();
//	//std::cout << schemaDocumentRoot << std::endl;
//	//if (!valijson::utils::loadDocument("/mnt/e/contrle_version/modle_code/mvMqttServer/conf/schema.json", schemaDocumentRoot)) {
//	//	cerr << "Failed to load schema document." << endl;
//	//	return 1;
//	//}
//
//	if (!valijson::utils::loadDocument("/mnt/e/contrle_version/modle_code/mvMqttServer/conf/event.json", targetDocumentRoot)) {
//		cerr << "Failed to load schema document." << endl;
//		return 1;
//	}
//    // 先判断目标json是什么类型的数据
//    // 方法类型 唯一能力值
//	Json::Value schemaDocument;
//	Json::Value targetDocument;
//    std::string mehodAndIdentifier = targetDocumentRoot.get("method", "").asString();
//    if (mehodAndIdentifier.empty()) {
//        cerr << "mehodAndIdentifier.empty()" << endl;
//        return -1;
//    }
//    auto identifier =getLastElement(mehodAndIdentifier,".");
//    auto mehod = mehodAndIdentifier.substr(0, mehodAndIdentifier.length() - identifier.length()-1);
//	std::cout << "identifier:" << identifier << std::endl;
//	std::cout << "mehod:" << mehod << std::endl;
//    targetDocument = targetDocumentRoot["params"];
//    if (mehod=="thing.property.post") {
//        schemaDocument = schemaDocumentRoot["properties"][identifier];
//    }
//    else if(mehod == "thing.event.post"){
//		schemaDocument = schemaDocumentRoot["events"][identifier];
//	}
//	else if (mehod == "thing.action.post") {
//		schemaDocument = schemaDocumentRoot["actions"][identifier]["inputData"];
//    }
//    else {
//        return -1;
//    }
//
//
//    if (test(schemaDocument, targetDocument) == 0) {
//        std::cout << "schema 验证通过" << std::endl;
//    }
//    return 0;
//}
Json::Value getJsonByValueL( VetcorData& object) {
	if (!object.isNormal())
	{
		std::cout << "no normal:" << std::endl;
		return NULL;
	}
	bool isStruct = false;
	bool isArray = false;
	int arraySpec = 0;
	int structSpec = 0;
	int StructLend = 0;
	int ArrayLen = 0;
	std::string structKeyName = "";
	std::string arrayKeyName = "";
	Json::Value tets;
	Json::Value root;
	for (auto itr : object.getVector()) {
		if (itr.getValueType() == ValueL::Array) {
			isArray = true;
			ArrayLen = itr.getTotal();
			arrayKeyName = itr.getkey();
			continue;
		}
		if (itr.getValueType() == ValueL::Struct) {
			isStruct = true;
			StructLend = itr.getTotal() - 1;
			structKeyName = itr.getkey();
			if (isArray) {
				arraySpec++;
				//if (ArrayLen <= 0) {
				//	ArrayLen = 0;
				//	isArray = false;
				//}地方
			}
			continue;
		}

		if (isArray) {
			arraySpec++;
			//ArrayLen--;
			if (arraySpec == ArrayLen) {
				isArray = false;
			}
			if (!isStruct) {
				addJson3(root[arrayKeyName], &itr);
				continue;
			}
		}
		if (isStruct)
		{
			structSpec += 1;
			addJson2(tets[structKeyName], &itr);
			if (structSpec == StructLend) {
				if (isArray) {
					root[arrayKeyName].append(tets[structKeyName]);
				}
				else if (arraySpec == ArrayLen && ArrayLen!=0) {
					root[arrayKeyName].append(tets[structKeyName]);
					arraySpec = 0;
				}
				else
				{
					root[structKeyName] = tets[structKeyName];
				}
				tets.clear();
				structSpec = 0;
				isStruct = false;
			}
			continue;
		}

		addJson2(root, &itr);
	}
	return std::move(root);
}

int main() {
	//加载物模型
	Json::Value tslDocumentRoot;
	Json::Value schemaDocumentRoot;

	if (!valijson::utils::loadDocument("/mnt/e/contrle_version/modle_code/mvMqttServer/conf/mvMqttServer.json", tslDocumentRoot)) {
		cerr << "Failed to load tslDocumentRoot." << endl;
		return 1;
	}
	//VetcorData object2;
	//object2 << ValueL("任务令牌1", "sasdasdasdsd") << 2>>1;
	//object2.getVector()[0].setId(5);
	//std::cout << object2.getVector()[0].getId() << std::endl;
	VetcorData object2;
	object2
		<< ValueL("任务令牌1", "sasdasdasdsd")
		<< ValueL("响应码2", "200")
		<< ValueL("通行策略表3", 0, ValueL::Array) << 2
		<< ValueL("通行策略表结构体4", 0, ValueL::Struct) << 1
		<< ValueL("1时间段类型5", 0)
		<< ValueL("1开始时间6", "2022-08-14 15:30:00")
		<< ValueL("1结束时间7", "2022-08-14 16:30:00")
		<< ValueL("1识别控制类型8", "900+901+902")
		<< ValueL("1身份控制类型9", "900+901+902")
		>> 1
		<< ValueL("通行策略表结构体4", 0, ValueL::Struct) << 1
		<< ValueL("2时间段类型5", 0)
		<< ValueL("2开始时间6", "2022-08-14 15:30:00")
		<< ValueL("2结束时间7", "2022-08-14 16:30:00")
		<< ValueL("2识别控制类型8", "900+901+902")
		<< ValueL("2身份控制类型9", "900+901+902")
		>> 1
		<< ValueL("通行策略表结构体4", 0, ValueL::Struct) << 1
		<< ValueL("3时间段类型5", 0)
		<< ValueL("3开始时间6", "2022-08-14 15:30:00")
		<< ValueL("3结束时间7", "2022-08-14 16:30:00")
		<< ValueL("3识别控制类型8", "900+901+902")
		<< ValueL("3身份控制类型9", "900+901+902")
		>> 1
		>> 2;
	object2 << ValueL("通行策略表4", 0, ValueL::Array) << 1;
	for (int i = 0; i <= 2; i++) {
		object2 << ValueL("通行策略表结构体4", 0, ValueL::Struct) << 1
			<< ValueL("3时间段类型5", 0)
			<< ValueL("3开始时间6", "2022-08-14 15:30:00")
			<< ValueL("3结束时间7", "2022-08-14 16:30:00")
			<< ValueL("3识别控制类型8", "900+901+902")
			<< ValueL("3身份控制类型9", "900+901+902") >> 1;
	}
	object2 >> 1;

	Json::Value resJson2 = getJsonByValueL(object2);
	std::cout << resJson2 << std::endl;
	//生成json schema
	//getSchemaProByTslPro(schemaDocumentRoot["properties"], tslDocumentRoot["properties"]);
	//getSchemaEveByTslEve(schemaDocumentRoot["events"], tslDocumentRoot["events"]);
	//getSchemaActByTslAct(schemaDocumentRoot["actions"], tslDocumentRoot["actions"]);
	//std::ofstream out1("/mnt/e/contrle_version/modle_code/mvMqttServer/conf/schema.json"); 
	//out1 << GetStringByJson(schemaDocumentRoot);
	//out1.close();

	// 加载json schema
	if (!valijson::utils::loadDocument("/mnt/e/contrle_version/modle_code/mvMqttServer/conf/schema.json", schemaDocumentRoot)) {
		cerr << "Failed to load tslDocumentRoot." << endl;
		return 1;
	}

	//生成输入json消息
	VetcorData object;
	object["设备升级模块:设备固件升级功能"]
		<< ValueL("method", "things.action.exec.设备升级模块:设备固件升级功能")
		<< ValueL("params", 4, ValueL::Struct) << 1
		<< ValueL("文件url", "wwww.test.com.file")
		<< ValueL("升级开始时间", "2022-08-16 09:27:55")
		<< ValueL("固件升级包版本信息", 1) >> 1;
	Json::Value targetDocumentRoot = getJsonByValueL(object);

	//解析method 
	Json::Value schemaDocument;
	Json::Value targetDocument;
    std::string mehodAndIdentifier = targetDocumentRoot.get("method", "").asString();
    if (mehodAndIdentifier.empty()) {
        cerr << "mehodAndIdentifier.empty()" << endl;
        return -1;
    }
    auto identifier =getLastElement(mehodAndIdentifier,".");
    auto mehod = mehodAndIdentifier.substr(0, mehodAndIdentifier.length() - identifier.length()-1);
	std::cout << "identifier:" << identifier << std::endl;
	std::cout << "mehod:" << mehod << std::endl;
    targetDocument = targetDocumentRoot["params"];

	//抽取jsonSchema片段
    if (mehod=="things.property.post") {
        schemaDocument = schemaDocumentRoot["properties"][identifier];
    }
	else if (mehod == "things.property.set") {
		schemaDocument = schemaDocumentRoot["properties"][identifier];
	}
    else if(mehod == "things.event.post"){
		schemaDocument = schemaDocumentRoot["events"][identifier];
	}
	else if (mehod == "things.tsevent.post") {
		schemaDocument = schemaDocumentRoot["events"][identifier];
	}
	else if (mehod == "things.action.exec") {
		schemaDocument = schemaDocumentRoot["actions"][identifier]["inputData"];
    }
    else {
        return -1;
    }
	//打印输入和输出
	std::cout << "schemaDocument:" << schemaDocument << std::endl;
	std::cout << "targetDocument:" << targetDocument << std::endl;
	//校验Json消息
	std::string desc = "";
	int rc = test(schemaDocument, targetDocument, desc);

	//响应json消息
	Json::Value resJson;
	if (rc == 0) {
			std::cout << "schema 验证通过" << std::endl;

			std::string res_method = mehod+"_reply." + identifier;
			VetcorData response;
			response["设备升级模块:设备固件升级功能"]
				<< ValueL("method", res_method)
				<< ValueL("响应码", 200);
			resJson = getJsonByValueL(response);
	}
	else {
			std::cout << "schema 验证失败" << std::endl;
			VetcorData response;
			std::string res_method = mehod + "_reply." + identifier;
			std::cout << desc << std::endl;
			response["设备升级模块:设备固件升级功能"]
				<< ValueL("method", res_method.c_str())
				<< ValueL("响应码", -1)
				<< ValueL("响应消息", desc.c_str());
			resJson = getJsonByValueL(response);
	}
	std::cout << resJson << std::endl;
	getchar();
	return 0;
}
